import { useMemberStore } from '@/stores'

// 设置基地址 与 拦截器
const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'

// 请求拦截器
uni.addInterceptor('request', {
  // 拦截前触发
  invoke(args: UniApp.RequestOptions) {
    // 不是 http 开头的 基地址 就拼接
    if (args.url.startsWith('http') === false) {
      // 就拼接
      args.url = baseURL + args.url
    }
    // 设置超时时间
    args.timeout = 100000
    // TODO: 给请求头添加 Authorization
    args.header = {
      'source-client': 'miniapp',
      ...args.header
    }
    // 获取token
    const store = useMemberStore()
    const token = store.profile?.token
    if (token) {
      args.header.Authorization = token
    }
  }
})

// 请求拦截器
uni.addInterceptor('uploadFile', {
  // 拦截前触发
  invoke(args: UniApp.RequestOptions) {
    // 不是 http 开头的 基地址 就拼接
    if (args.url.startsWith('http') === false) {
      // 就拼接
      args.url = baseURL + args.url
    }
    // 设置超时时间
    args.timeout = 10000
    // TODO: 给请求头添加 Authorization
    args.header = {
      'source-client': 'miniapp',
      ...args.header
    }
    // 获取token
    const store = useMemberStore()
    const token = store.profile?.token
    if (token) {
      args.header.Authorization = token
    }
  }
})

// 定义服务器响应回来的数据类型
type ResDataType<T> = {
  code: string
  msg: string
  result: T
}

// 请求函数的封装
export function http<T>(options: UniApp.RequestOptions) {
  // 返回Promise对象
  return new Promise<ResDataType<T>>((resolve, reject) => {
    // 调用 uni.request 方法
    uni.request({
      ...options,
      // 成功
      success: (res) => {
        // 处理 请求成功的  401 其他的情况
        // 1. 成功 res.statusCode 大于等于200 并且小于300
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 调用
          resolve(res.data as ResDataType<T>)
        } else if (res.statusCode === 401) {
          // 2. 401 的错误 清除用户的信息
          const store = useMemberStore()
          // 调用clearProfile
          store.clearProfile()
          // 跳转到 登录页
          uni.navigateTo({
            url: '/pages/login/login'
          })
        } else {
          // 其他错误
          uni.showToast({
            title: (res.data as ResDataType<T>).msg || '其他错误',
            icon: 'none'
          })
          reject(res)
        }
      },
      // 失败
      fail: (err) => {
        // 给用户提示
        uni.showToast({
          title: '请求发生了错误',
          icon: 'none'
        })
        reject(err)
      }
    })
  })
}
